# dictionary 映射类型数据 字典
# 键是不可变类型的（数字、字符串、元组）
# 值可以是任何对象。

# 何时使用字典
# ID到名称映射。
# 对象到计数的映射。
# 特征到特征值的名称。
# 属性对该属性的值的名称

# user = {}
# # user = dict()
# user['name'] = 'Foobar'  # 新建一对键值对，key是name value是Foobar
# print(user)  # {'name': 'Foobar'}
#
# user['email'] = 'foo@bar.com'
# print(user)  # {'name': 'Foobar', 'email': 'foo@bar.com'}
#
# the_name = user['name']
# print(the_name)  # Foobar
#
# field = 'name'
# the_value = user[field]
# print(the_value)  # Foobar
# # 这个时候就是更新
# user['name'] = 'Edith Piaf'
# print(user)  # {'name': 'Edith Piaf', 'email': 'foo@bar.com'}

# keys 键
#
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# print(user)  # {'lname': 'Bar', 'fname': 'Foo'}
#
# print(user.keys())  # ['lname', 'fname']
# Loop over keys
# # 在键上循环  遍历键
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# for k in user.keys():
#     print(k)
#
# # lname
# # fname
#
# for k in user.keys():
#     print("{} -> {}".format(k, user[k]))

# lname -> Bar
# fname -> Foo

# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# for k in user:
#     print("{} -> {}".format(k, user[k]))

# lname -> Bar
# fname -> Foo

# Loop using items  项目 元组

# people = {
#     "foo": "123",
#     "bar": "456",
#     "qux": "789",
# }
#
# for name, uid in people.items():
#     print("{} => {}".format(name, uid))
# print("{} => {}".format(name, people[name]))
# foo => 123
# bar => 456
# qux => 789
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# for t in user.items():  # returns tuples
#     # print(type(t))
#     # print(t)
#     print("{} -> {}".format(t[0], t[1]))
#     print("{} ->222 {}".format(*t))  # * 解包的意思 解包 列表或者元组 之类的东西，

#
# def func(*args, **kwargs):
#     pass

# lname -> Bar
# fname -> Foo

# values 只关心值
#
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# print(user)  # {'lname': 'Bar', 'fname': 'Foo'}
#
# # print(user.keys())  # ['lname', 'fname']
#
# print(user.values())  # ['Bar', 'Foo']
# for v in user.values():
#     print(v)


# Not existing key
# 如果我们试图获取一个不存在的键的值，我们会得到一个异常。
#
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
#     # 'email': 'xxx@xx.com',
# }
# print(user)
# print(user['fname'])
# print(user['email'])
#
# print(12312)
# print(12312)
# print(12312)
# print(12312)

# Get key
# If we use the get method, we get None if the key does not exist.
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
#     'address': None,
#     'xxx': [12312, 123123],
# }
#
# print(user)
# print(user.get('fname'))
# print(user.get('address'))
# print(user.get('email'))  # # get获取email的值，但是email不存在，默认返回None
#
# print(user.get('answer', 42))  # get获取某个键的值，如果这个键在这字典里不存在，那就返回42
# print(user.get('address', 23))

# Does the key exist?

# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
#
# print('fname' in user)  # True
# print('email' in user)  # False
# print('Foo' in user)  # False
#
# for k in ['fname', 'email', 'lname']:
#     # 判断k在不在这个字典里边
#     if k in user:
#         # 这个键在这字典里，执行打印
#         print("{} => {}".format(k, user[k]))


# fname => Foo
# lname => Bar

# Does the value exist?
#
# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
# }
# print(user.values())
# print('fname' in user.values())  # False
# print('Foo' in user.values())  # True

# Delete key

# user = {
#     'fname': 'Foo',
#     'lname': 'Bar',
#     'email': 'foo@bar.com',
# }
#
# print(user)  # {'lname': 'Bar', 'email': 'foo@bar.com', 'fname': 'Foo'}
#
# fname = user['fname']
# del user['fname']  # 删除
# print(fname)  # Foo
# print(user)  # {'lname': 'Bar', 'email': 'foo@bar.com'}
#
# lname_was = user.pop('lname')  # 删除
# print(lname_was)  # Bar
# print(user)  # {'email': 'foo@bar.com'}


# List of dictionaries
#
# people = [
#     {
#         'name': 'Foo Bar',
#         'email': 'foo@example.com'
#     },
#     {
#         'name': 'Qux Bar',
#         'email': 'qux@example.com',
#         'address': 'Borg, Country',
#         'children': [
#             'Alpha',
#             'Beta'
#         ]
#     }
# ]
#
# print(people)
# print(people[0]['name'])
# print(people[1]['children'][0])


# def func(p):
#     print('in func', p)
#     return p['name']
#
#
# # print(list(map(lambda p: p['name'], people)))  # map(func，可迭代对象)  把后边这个可迭代的对象，挨个遍历，做func
# print(list(map(func, people)))  # map(func，可迭代对象)  把后边这个可迭代的对象，挨个遍历，做func

# my_list = []
# for p in people:
#     my_list.append(p['name'])
# print(my_list)

# Shared dictionary
#
# people = [
#     {
#         "name": "Foo",
#         "id": "1",
#     },
#     {
#         "name": "Bar",
#         "id": "2",
#     },
#     {
#         "name": "Moo",
#         "id": "3",
#     },
# ]
#
# by_name = {}  # 一个空字典
# by_id = {}
# for p in people:
#     by_name[p['name']] = p
#     by_id[p['id']] = p
# print(by_name)
# # {'Foo': {'name': 'Foo', 'id': '1'}, 'Bar': {'name': 'Bar', 'id': '2'}, 'Moo': {'name': 'Moo', 'id': '3'}}
# print(by_id)
# # {'1': {'name': 'Foo', 'id': '1'}, '2': {'name': 'Bar', 'id': '2'}, '3': {'name': 'Moo', 'id': '3'}}
# print(by_name["Foo"])
# by_name["Foo"]['email'] = 'foo@weizmann.ac.il'  # 添加个键值对 email - foo@weizmann.ac.il
# print(by_name["Foo"])
#
# print(by_id["1"])
# print(people[0])


# immutable collection: tuple as dictionary key
# 不可变集合类型：作为字典项的元组

# points = {}
# p1 = (2, 3)
#
# points[p1] = 'Joe'
# points[(17, 5)] = 'Jane'
#
# print(points)
# print()
# for k in points.keys():
#     print(k)
#     # print(k.__class__.__name__)
#     print(type(k))
#     print(points[k])

# immutable numbers: numbers as dictionary key
# number = {
#     23: "Twenty three",
#     17: "Seventeen",
#     3.14: "Three dot fourteen",
#     42: "The answer",
# }
#
# print(number)
# print(number[42])
# print(number[3.14])

# Sort dictionary by value

# scores = {
#     'Foo': 10,
#     'Bar': 34,
#     'Miu': 88,
# }
#
# print(scores)  # {'Miu': 88, 'Foo': 10, 'Bar': 34}
#
# sorted_names = sorted(scores)  # "sort dictionary" sorts the keys
# print(sorted_names)  # ['Bar', 'Foo', 'Miu']
# for s in sorted_names:
#     print("{} {}".format(s, scores[s]))
#
# # sort the values, but we cannot get the keys back!
# print(sorted(scores.values()))  # [10, 34, 88]
#
# print('')
#
# # sort using a lambda expression
# sorted_names = sorted(scores, key=lambda x: scores[x])
# print(sorted_names)
# for k in sorted_names:
#     print("{} : {}".format(k, scores[k]))
#
# # Foo : 10
# # Bar : 34
# # Miu : 88
#
# print('')
#
# # sort the keys according to the values:
# sorted_names = sorted(scores, key=scores.__getitem__)
# for k in sorted_names:
#     print("{} : {}".format(k, scores[k]))
#
# # Foo : 10
# # Bar : 34
# # Miu : 88
#
#
# Sort dictionary keys by value
# scores = {
#     "Jane": 30,
#     "Joe": 20,
#     "George": 30,
#     "Hellena": 90,
# }
#
# for name in scores.keys():
#     print(f"{name:<8} {scores[name]}")
#
# print('')
# for name in sorted(scores.keys()):
#     print(f"{name:8} {scores[name]}")
#
# print('')
# for val in sorted(scores.values()):
#     print(f"{val:<8}")
#
# print('')
# for name in sorted(scores.keys(), key=lambda x: scores[x]):
#     print(f"{name:8} {scores[name]}")

# Change order of keys in dictionary - OrderedDic

# from collections import OrderedDict
#
# d = OrderedDict()
# d['a'] = 1
# d['b'] = 2
# d['c'] = 3
# d['d'] = 4
#
# print(d)
# d.move_to_end('a')
#
# print(d)
# d.move_to_end('d', last=False)  # 移动到了第一个位置
#
# print(d)
#
# for key in d.keys():
#     print(key)

# Set order of keys in dictionary - OrderedDict
# from collections import OrderedDict
#
# d = {}
# d['a'] = 1
# d['b'] = 2
# d['c'] = 3
# d['d'] = 4
# print(d)
#
# planned_order = ('b', 'c', 'd', 'a')
# e = OrderedDict(sorted(d.items(), key=lambda x: planned_order.index(x[0])))
# print(e)
#
# print('-----')
# # Create index to value mapping dictionary from a list of values
# planned_order = ('b', 'c', 'd', 'a')
# plan = dict(zip(planned_order, range(len(planned_order))))
# print(plan)
# # d.items() (a,1),(b,2),(c,3),(d,4)      # 这的x就是 ('a',1)
# f = OrderedDict(sorted(d.items(), key=lambda x: plan[x[0]]))
# print(f)

# 练习
# 练习：计数字符
# 给定一个长文本，计算一下每个字符出现的次数？
text = """
This is a very long text.
OK, maybe it is not that long after all.
"""

# a 5
# b ..

# 练习：计数单词
words = ['Wombat', 'Rhino', 'Sloth', 'Tarantula', 'Sloth', 'Rhino', 'Sloth']

# Wombat:1
# Rhino:2
# Sloth:3
# Tarantula:1

# 练习
# 有一段网站日志的文本

log_text = """
127.0.0.1 - - [10/Apr/2007:10:39:11] "GET / HTTP/1.1" 500 606 "-"
127.0.0.1 - - [10/Apr/2007:10:39:11] "GET /favicon.ico HTTP/1.1" 200 766 "-"
139.12.0.2 - - [10/Apr/2007:10:40:54] "GET / HTTP/1.1" 500 612 "-"
139.12.0.2 - - [10/Apr/2007:10:40:54] "GET /favicon.ico HTTP/1.1" 200 766 "-"
127.0.0.1 - - [10/Apr/2007:10:53:10] "GET / HTTP/1.1" 500 612 "-"
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET / HTTP/1.0" 200 3700 "-"
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET /style.css HTTP/1.1" 200 614
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET /img/pti-round.jpg HTTP/1.1" 200 17524
127.0.0.1 - - [10/Apr/2007:10:54:21] "GET /unix_sysadmin.html HTTP/1.1" 200 3880
217.0.22.3 - - [10/Apr/2007:10:54:51] "GET / HTTP/1.1" 200 34 "-"
217.0.22.3 - - [10/Apr/2007:10:54:51] "GET /favicon.ico HTTP/1.1" 200 11514 "-"
217.0.22.3 - - [10/Apr/2007:10:54:53] "GET /cgi/pti.pl HTTP/1.1" 500 617
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET / HTTP/0.9" 200 3700 "-"
217.0.22.3 - - [10/Apr/2007:10:58:27] "GET / HTTP/1.1" 200 3700 "-"
217.0.22.3 - - [10/Apr/2007:10:58:34] "GET /unix.html HTTP/1.1" 200 3880
217.0.22.3 - - [10/Apr/2007:10:58:45] "GET /talks/read.html HTTP/1.1" 404 311
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET /img/pti-round.jpg HTTP/1.1" 200 17524
127.0.0.1 - - [10/Apr/2007:10:54:08] "GET /img/pti-round.jpg HTTP/1.1" 200 17524
127.0.0.1 - - [10/Apr/2007:10:54:21] "GET /unix_sysadmin.html HTTP/1.1" 200 3880
127.0.0.1 - - [10/Apr/2007:10:54:21] "GET /unix_sysadmin.html HTTP/1.1" 200 3880
217.0.22.3 - - [10/Apr/2007:10:54:51] "GET / HTTP/1.1" 200 34 "-"
"""

# 统计每个ip地址访问的次数
# 期望输出

# 127.0.0.1     12
# 139.12.0.2     2
# 217.0.22.3     7

# 练习：计数DNA碱基
# 给定这样的序列：“ACTNGTGCTYGATRGTAGCYXGTN”，打印出元素的百分比情况，得到以下结果

# A 3 - 12.50 %
# C 3 - 12.50 %
# G 6 - 25.00 %
# N 2 - 8.33 %
# R 1 - 4.17 %
# T 6 - 25.00 %
# X 1 - 4.17 %
# Y 2 - 8.33 %
